
import BaseModel from "../../../cfw/mvc/BaseModel";
import { MapList } from "../../../cfw/struct/MapList";
import { engine } from "../../../engine/engine";
import { IBuffModel } from "./IBuffModel";
import { IBuffTarget } from "./IBuffTarget";


export abstract class BuffMgr<T extends IBuffTarget> extends BaseModel {
    static ADD_BUFF = 'ADD_BUFF'
    static REMOVE_BUFF = 'REMOVE_BUFF'

    protected _speStateType: number = 0;
    protected _target: T;

    set speStateType(t: number) {
        this._speStateType = t;
    }

    get speStateType() {
        return this._speStateType;
    }
    set target(t: T) {
        this._target = t;
    }

    get target() {
        return this._target;
    }
    protected _buffMap: { [type: number]: MapList<number, IBuffModel> } = {}
    hasSpecialState(speId: number) {
        let mapList = this._buffMap[this.speStateType];
        if (mapList) {
            let spe = mapList.get(speId)
            if (spe && !spe.isFinish()) {
                return true;
            }
        }
        return false
    }

    protected abstract createBuff(buffModel: IBuffModel, attacker: IBuffTarget): IBuffModel;

    add(buffModel: IBuffModel, attacker: IBuffTarget): boolean {
        // let type: BuffTypeModel = buffModel.getSpecialState();
        let type = buffModel.getBuffType();
        let speList = buffModel.getSpecialState();
        for (let index = 0; index < speList.length; index++) {
            const speId = speList[index];
            if (this.hasSpecialState(speId)) {
                engine.log('被身上的某些特殊效果作用,以至于没有得到这个buff speId ', speId)
                return false;
            }
        }

        let data = this._buffMap[type]
        if (!data) {
            data = new MapList()
            this._buffMap[type] = data;
        }
        let key = buffModel.getBuffKey();

        let buff = data.get(key)
        if (!buff) {
            buff = this.createBuff(buffModel, attacker)
            //触发次数大于1的才需要不断更新
            if (buffModel.getTriggerCount() > 1) {
                data.set(key, buff)
            }
        }
        if (buff) {
            buff.start();
            if (!buff.isFinish()) {
                this.emit(BuffMgr.ADD_BUFF, buff)
            }
        } else {
            return false;
        }

        return true;
    }

    remove(buffModel: IBuffModel) {
        let type = buffModel.getBuffType();
        let data = this._buffMap[type]
        if (!data) {
            return;
        }
        let key = buffModel.getBuffKey();

        let buff: IBuffModel = data.get(key)
        if (buff) {
            buff.end();
            data.delete(key)
        }
    }
}